package cn.xorange.commons.utils.captcha;

import cn.xorange.commons.utils.cache.ICacheService;
import cn.xorange.commons.utils.configuration.constants.UtilsErrorCode;
import cn.xorange.commons.utils.id.IdUtils;
import cn.xorange.commons.utils.codec.BaseUtils;
import com.google.code.kaptcha.Producer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.FastByteArrayOutputStream;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Objects;


/**
 * @author yangjian
 */
@Slf4j
@Configuration
public class CaptchaService{

    @Resource()
    private Producer captchaProducer;

    @Resource()
    private Producer captchaProducerMath;

    @Resource
    ICacheService cacheService;

    /**
     * 获取验证码
     * @param isMath 是否是数组计算 否则获取字符验证
     * @param isImg  是否是图片
     * @return Captcha
     */
    public Captcha getVerifyCode(Boolean isMath, Boolean isImg){

        // 保存验证码信息
        String uuid = IdUtils.fastSimpleUUID();
        String capStr = null;
        String code = null;
        // 生成验证码0
        if (Boolean.TRUE.equals(isMath)) {
            // 数字运算
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
        }else {
            // 简单文字
            capStr = code = captchaProducer.createText();
        }


        if(Boolean.TRUE.equals(isImg)){
            // 为图片
            BufferedImage image = null;
            if (Boolean.TRUE.equals(isMath)){
                image = captchaProducerMath.createImage(capStr);
            }else {
                image = captchaProducer.createImage(capStr);
            }
            // 转换流信息写出
            FastByteArrayOutputStream os = new FastByteArrayOutputStream();
            try {
                ImageIO.write(image, "jpg", os);
            }
            catch (IOException e) {
                return new Captcha(UtilsErrorCode.CAPTCHA_CREATE_ERROR);
            }
            capStr = BaseUtils.encodeBase64(os.toByteArray());
        }
        return new Captcha(uuid,capStr,code);

    }


    /**
     * @param uuid 前台传uuid
     * @param userCode 前台传 用户输入code
     * @return 1 通过 2过期 3参数缺失或错误
     */
    public Captcha checkCaptcha(String uuid,String userCode) {

        Captcha captcha = new Captcha(uuid);
        UtilsErrorCode code;
        if (Objects.isNull(uuid) || uuid.isEmpty()) {
            code = UtilsErrorCode.CAPTCHA_UUID_NULL;
        }
        else if (Objects.isNull(userCode) || userCode.isEmpty()) {
            code = UtilsErrorCode.CAPTCHA_CODE_NULL;
        }else {
            String verifyCode = cacheService.getCacheObject(captcha.cacheKey());
            if (Objects.isNull(verifyCode)|| verifyCode.isEmpty()){
                code = UtilsErrorCode.CAPTCHA_EXPIRE;
            }else {
                if (!verifyCode.equalsIgnoreCase(userCode)) {
                    code = UtilsErrorCode.CAPTCHA_NO_MATCH;
                }else {
                    code = UtilsErrorCode.SUCCESS;
                }
            }
        }
        captcha.setStatus(code.getStatus());
        captcha.setSysCode(code.getCode());
        captcha.setMsg(code.getMsg());
        return captcha;
    }

}
